<?php
namespace app\command\generate;

use app\command\Generate;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\Output;
use think\Db;

class Resource extends Generate {

    protected $output;

    protected function configure()
    {
        parent::configure();
        $this->addArgument("table",Argument::OPTIONAL,"the name of table");
        $this->setName('generate:resource')->setDescription('generate backend controller model validate service ');
    }

    protected function getStub()
    {
        $path = dirname(__FILE__).DS."stubs".DS."validate.plain.stub";
        return $path;
    }

    /**
     * 生成 controller类 model类 validate类 service类
     * @param Input $input
     * @param Output $output
     * return null
     */
    protected function execute(Input $input, Output $output)
    {
        $name = $input->getArgument("name");
        $table= $input->getArgument("table");
        if(empty($table)) $table = $name;
        $name = ucfirst($name);
        $table = ucfirst($table);
        $this->output = $output;
        try{
            $this->createController($name,$table);
            $this->createModel($table);
            $this->createService($table);
            $this->createValidate($table);
        }catch (\Exception $e){
            $output->writeln("Error: ".$e->getMessage());
        }

    }


    protected function createController($name,$table){
        $controllerBasePath = APP_PATH.'admin'.DS.'controller'.DS;
        if(!is_dir($controllerBasePath)){
            mkdir($controllerBasePath,'0755');
        }
        $path = $controllerBasePath.$name.'.php';
        if(file_exists($path)){
            throw new \Exception("controller file exists");
        }
        $templatePath = dirname(__FILE__).DS.'stubs'.DS."controller.stub";

        $content = file_get_contents($templatePath);
        $content = str_replace(['{%controllerName%}','{%tableName%}'],[$name,$table],$content);
        file_put_contents($path,$content);
        $this->output->writeln($path." create success!");
    }


    protected function createModel($table){
        $controllerBasePath = APP_PATH.'common'.DS.'model'.DS;
        if(!is_dir($controllerBasePath)){
            mkdir($controllerBasePath,'0755');
        }
        $path = $controllerBasePath.$table.'.php';
        if(file_exists($path)){
            throw new \Exception("model file exists");
        }
        $templatePath = dirname(__FILE__).DS.'stubs'.DS."model.stub";

        $content = file_get_contents($templatePath);
        $content = str_replace(['{%tableName%}'],[$table],$content);
        file_put_contents($path,$content);
        $this->output->writeln($path." create success!");
    }


    protected function createValidate($table){
        $controllerBasePath = APP_PATH.'common'.DS.'validate'.DS;
        if(!is_dir($controllerBasePath)){
            mkdir($controllerBasePath,'0755');
        }
        $path = $controllerBasePath.$table.'.php';
        if(file_exists($path)){
            throw new \Exception("validate file exists");
        }
        $templatePath = dirname(__FILE__).DS.'stubs'.DS."validate.stub";

        $table = $this->uncamelize($table);

        //根据表生成基本的验证
        $res = Db::query("SHOW FULL COLUMNS FROM `".strtolower($table)."`");
        $rule = '';
        $message = '';
        $save = '';
        $update = '';
        foreach($res as $key => $val ){
            $rule .= "            '".$val['Field']."'=>'require',\r\n";
            $message .= "            '".$val['Field'].".require'=>'请输入".$val['Comment']."',\r\n";
            if($val['Field'] != 'id'){
                $save .= "'".$val['Field']."',";
            }
            $update .= "'".$val['Field']."',";
        }
        $rule = trim($rule,"\r\n");
        $message = trim($message,"\r\n");
        $save = trim($save,",");
        $update = trim($update,",");
        $ruleString = <<<STR
        public \$rule = [
{$rule}
        ];
STR;

        $messageString = <<<STR
        public \$message = [
{$message}
        ];
STR;

        $sceneString = <<<STR
        public \$scene = [
            'save'=>[{$save}],
            'update'=>[{$update}],
        ];
STR;


        $code = $ruleString."\r\n\r\n".$messageString."\r\n\r\n".$sceneString;

        $content = file_get_contents($templatePath);
        $content = str_replace(['{%tableName%}','{%code%}'],[$table,$code],$content);
        file_put_contents($path,$content);

        $this->output->writeln($path." create success!");
    }

    protected function createService($table){
        $controllerBasePath = APP_PATH.'common'.DS.'service'.DS;
        if(!is_dir($controllerBasePath)){
            mkdir($controllerBasePath,'0755');
        }
        $path = $controllerBasePath.$table.'.php';
        if(file_exists($path)){
            throw new \Exception("service file exists");
        }
        $templatePath = dirname(__FILE__).DS.'stubs'.DS."service.stub";

        $content = file_get_contents($templatePath);
        $content = str_replace(['{%tableName%}','{%tableNameLower%}'],[$table,strtolower($table)],$content);
        file_put_contents($path,$content);
        $this->output->writeln($path." create success!");
    }

    /**
 　　* 驼峰命名转下划线命名
 　　* 思路:
 　　* 小写和大写紧挨一起的地方,加上分隔符,然后全部转小写
 　　*/
     private function uncamelize($camelCaps,$separator='_')
     {
         return strtolower(preg_replace('/([a-z])([A-Z])/', "$1" . $separator . "$2", $camelCaps));
     }

}